package com.huirui.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huirui.server.exception.BaseException;
import com.huirui.server.mapper.BrandMapper;
import com.huirui.server.pojo.dto.BrandDto;
import com.huirui.server.pojo.entity.Brand;
import com.huirui.server.pojo.entity.Product;
import com.huirui.server.pojo.result.PageResult;
import com.huirui.server.pojo.vo.BrandDetailVo;
import com.huirui.server.pojo.vo.BrandWithLetterVo;
import com.huirui.server.service.BrandService;
import com.huirui.server.service.ProductService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yujun
 * @description 针对表【t_brand】的数据库操作Service实现
 * @createDate 2025-11-07 22:51:28
 */
@Service
@Slf4j
public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand>
        implements BrandService {

    @Resource
    private ProductService productService;

    @Override
    public void addNewBrand(BrandDto brandDto) {
        Brand brand = BeanUtil.copyProperties(brandDto, Brand.class);
        brand.setCreateTime(LocalDateTime.now());
        brand.setUpdateTime(LocalDateTime.now());
        save(brand);
    }

    @Override
    public PageResult<Brand> listBrand(String brandName, int page, int pageSize) {
        IPage<Brand> iPage = new Page<>(page, pageSize);
        lambdaQuery()
                .like(StringUtils.isNotBlank(brandName), Brand::getBrandName, brandName)
                .orderByDesc(Brand::getBrandWeight)
                .orderByDesc(Brand::getCreateTime)
                .orderByDesc(Brand::getId)
                .page(iPage);
        return PageResult.from(iPage);
    }

    @Override
    @Transactional
    public void deleteBrand(Long id) {
        lambdaUpdate()
                .eq(Brand::getId, id)
                .remove();
        productService
                .lambdaUpdate()
                .eq(Product::getBrandId, id)
                .set(Product::getUpdateTime, LocalDateTime.now())
                .set(Product::getBrandId, null)
                .update();
    }

    @Override
    public void updateBrand(BrandDto brandDto) {
        if (brandDto.getId() == null) {
            throw new BaseException("品牌ID不能为NULL");
        }
        lambdaUpdate()
                .eq(Brand::getId, brandDto.getId())
                .set(StringUtils.isNotBlank(brandDto.getBrandName()), Brand::getBrandName, brandDto.getBrandName())
                .set(Brand::getUpdateTime, LocalDateTime.now())
                .set(StringUtils.isNotBlank(brandDto.getBrandProfile()), Brand::getBrandProfile, brandDto.getBrandProfile())
                .set(StringUtils.isNotBlank(brandDto.getBrandImage()), Brand::getBrandImage, brandDto.getBrandImage())
                .set(ObjectUtils.isNotEmpty(brandDto.getBrandWeight()), Brand::getBrandWeight, brandDto.getBrandWeight())
                .update();
    }

    @Override
    public BrandDetailVo getBrandDetailInfo(Long brandId) {
        return baseMapper.getBrandDetailInfo(brandId);
    }

    @Override
    public List<BrandWithLetterVo> listBrandWithLetter() {
        List<Brand> list = lambdaQuery().list();
        Map<String, List<BrandDetailVo>> collect = list.stream().collect(Collectors.groupingBy(
                this::getLetter,
                Collectors.mapping(this::mappingBrand2BrandDetail, Collectors.toList())
        ));
        return collect.entrySet().stream().map(
                        entry -> {
                            BrandWithLetterVo vo = new BrandWithLetterVo();
                            vo.setLetter(entry.getKey());
                            vo.setBrandList(entry.getValue());
                            return vo;
                        }
                ).sorted(Comparator.comparing(BrandWithLetterVo::getLetter))
                .toList();
    }

    private BrandDetailVo mappingBrand2BrandDetail(Brand brand) {
        BrandDetailVo brandDetailVo = new BrandDetailVo();
        brandDetailVo.setBrandId(brand.getId());
        brandDetailVo.setBrandName(brand.getBrandName());
        brandDetailVo.setBrandImage(brand.getBrandImage());
        return brandDetailVo;
    }

    private String getLetter(Brand brand) {
        if (isFirstCharLetterOrChinese(brand.getBrandName())) {
            return String.valueOf(Character.toUpperCase(PinyinUtil.getFirstLetter(brand.getBrandName(), ",").toCharArray()[0]));
        } else {
            return "#";
        }
    }


    /**
     * 判断字符串首字符是否为 字母（a-z/A-Z）或 汉字
     *
     * @param str 输入字符串（可含空格、null、特殊字符）
     * @return true=首字符是字母/汉字；false=首字符不是（或字符串无效）
     */
    public static boolean isFirstCharLetterOrChinese(String str) {
        // 1. 预处理：判断字符串是否有效（非null、非空、非纯空格）
        if (str == null || str.trim().isEmpty()) {
            return false; // 无效字符串，直接返回false
        }

        // 2. 提取首字符（去空格后取第一个字符）
        char firstChar = str.trim().charAt(0);

        // 3. 判断：首字符是字母 OR 是汉字
        return isLetter(firstChar) || isChinese(firstChar);
    }

    /**
     * 辅助方法：判断字符是否为字母（a-z/A-Z）
     */
    private static boolean isLetter(char c) {
        // Character.isLetter() 直接判断是否为字母（兼容大小写）
        return Character.isLetter(c);
    }

    /**
     * 辅助方法：判断字符是否为汉字（常用汉字 Unicode 范围：0x4E00 ~ 0x9FA5）
     * 注：该范围覆盖99%以上常用中文，生僻字需扩展范围（如 0x3400~0x4DBF 等，按需添加）
     */
    private static boolean isChinese(char c) {
        // 常用汉字编码区间：0x4E00（一） ~ 0x9FA5（龥）
        return c >= 0x4E00 && c <= 0x9FA5;
    }


}




